﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CommonLib;
namespace Constructor
{
    [Serializable]
    public partial class Slot : Object, ISlot
    {
        private Frame _frame;
        private SlotType _type;
        private string _name;
        private Domain _domain;
        private string _domainID;
        private Frame _subframe;
        public bool isOwn { get; set; }
        public event EventHandler ChangeType;
        public event EventHandler Change;
        public bool CanBeNull { get; set; }
        public Slot(string name)
        {
            Name = name;
            ID = Guid.NewGuid().ToString();
        }

        public Slot(Frame frame)
        {
            _frame = frame;
            Change += new EventHandler(_frame.slot_Change);
            _type = Properties.Settings.Default.defaulSlotType;
            Inherit = Properties.Settings.Default.defaultInherit;
            CanBeNull = false;
            isOwn = true;
            Name = _frame.GetSlotName();
            ID = Guid.NewGuid().ToString();
        }
        public string ID { get; set; }
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
            }
        }
        public string FullName
        {
            get
            {
                return _frame.Name + "." + Name;
            }
        }
        public Frame Frame { get { return _frame; } }
        public string FrameID
        {
            get
            {
                return Frame.ID;
            }
        }
        public string DomainID
        {
            get
            {
                return _domainID;
            }
            set
            {
                _domain = new Domain(value); _domainID = value;
            }
        }
        public object Default { get; set; }
        public TypeInherit Inherit { get; set; }
        public string Marker { get; set; }
        public string Question { get; set; }
        public bool Necess { get; set; }
        public Frame Subframe
        {
            get
            {
                return _subframe;
            }
            set
            {
                _subframe = value;
                OnChangeType(EventArgs.Empty);
            }
        }
        public SlotType Type
        {
            get
            {
                return _type;
            }
            set
            {
                _type = value;
                OnChangeType(EventArgs.Empty);
            }
        }
        public Domain Domain
        {
            get
            {
                return _domain;
            }
        }
        public Production Production { get; set; }
        public ListViewItem Item { get; set; }
        public void SaveInDataSet(DataSet ds)
        {
            DataTable dt = ds.Tables["Slots"];
            DataRow row = dt.NewRow();
            row["name"] = Name;
            row["id_frame"] = _frame.ID;
            row["type"] = Type.ToString();
            row["inherit"] = Inherit.ToString();
            row["id"] = ID;
            switch (Type)
            {
                case SlotType.AKO:
                    row["subframe"] = Subframe.ID;
                    break;
                case SlotType.Error:
                    row["subframe"] = Subframe.ID;
                    break;
                case SlotType.Next:
                    row["subframe"] = Subframe.ID;
                    break;
                case SlotType.SubFrame:
                    if (Subframe != null)
                        row["subframe"] = Subframe.ID;
                    row["canbenull"] = CanBeNull.ToString();
                    break;
                case SlotType.Production:
                    Production.SaveInDataSet(ds);
                    break;
                case SlotType.Regular:
                    row["id_domain"] = DomainID;
                    row["default"] = Default;
                    break;
            }
            dt.Rows.Add(row);
        }
        public override string ToString()
        {
            return FullName;
        }
        public void RepaintItem()
        {
            string domain = "";
            string typedomain = "";
            if (Domain != null && Type != SlotType.Production)
            {
                domain = DomainID;
                if (Type == SlotType.Regular)
                    switch (Domain.Type)
                    {
                        case CommonLib.DomainType.Enum:
                            typedomain = "Перечислимый";
                            break;
                        case CommonLib.DomainType.Number:
                            typedomain = "Числовой(" + Domain.MinValue.ToString() + ".." + Domain.MaxValue.ToString() + ")";
                            break;
                    }
            }
            Item.SubItems[0].Text = Name;
            Item.SubItems[1].Text = Type.ToString();
            Item.SubItems[2].Text = domain;
            Item.SubItems[3].Text = typedomain;
        }
        public bool isUsedDomain(string name)
        {
            return DomainID == name;
        }
        public Slot Clone(Frame parent)
        {
            Slot s = new Slot(parent);
            s.DomainID = DomainID;
            s.Name = Name;
            s.Type = Type;
            s.Inherit = Inherit;
            s.Default = Default;
            s.CanBeNull = CanBeNull;
            s.isOwn = isOwn;
            s.Item = Item;
            s.ID = ID;
            if (Subframe != null)
                s.Subframe = Subframe.Clone() as Frame;
            else
                s.Subframe = null;
            if (Production != null)
                s.Production = Production.Clone(s);
            return s;
        }
        protected virtual void OnChangeType(EventArgs e)
        {
            if (ChangeType != null)
                ChangeType(this, e);
            OnChange(e);
        }
        protected virtual void OnChange(EventArgs e)
        {
            if (Change != null)
                Change(this, e);
        }
        public bool Equals(Slot s)
        {
            return s.Name == Name && s.Type == Type && s.DomainID == DomainID;
        }
    }
}
